<?php

namespace app\system\controller;

use app\common\model\AttachmentModel;
use think\facade\Filesystem;

class UploadController extends BaseController
{

  /**
   * 无需登录的方法
   * @var array
   */
  protected $noLogin = [];

  /**
   * 不需要检测权限的方法
   * @var array
   */
  protected $noCheck = ['file'];

  /**
   * 附件模型
   * @var mixed
   */
  protected $model = null;

  /**
   * 初始化
   */
  public function __construct()
  {
    parent::__construct();
    $this->model = new AttachmentModel();
  }

  /**
   * 文件上传
   * @return false|string
   * @throws \Exception
   */
  public function file()
  {
    $opener = $this->request->param('opener'); //附件字段
    $driver = $this->request->param('driver', config('filesystem.default'));
    $files  = $this->request->file();
    $type   = $this->request->param('type', 'image');
    $ext    = $this->request->param('ext');
    $data   = [];
    try {
      $groupId  = $this->request->param('group_id', 0);
      $config   = config("filesystem.disks.{$driver}");
      $valid    = $this->getValidRule($type); //验证规则
      $validExt = !empty($ext) ? $ext : $valid; //存在ext参数优先验证ext
      if (empty($files)) abort(500, '请选择上传文件');
      $fileField = $opener == 'ckeditor' ? 'upload' : 'file'; //上传文件字段
      $this->validate($files, [
        "{$fileField}|上传文件" => "fileExt:{$validExt}"
      ]);
      $dataList = [];
      if ($opener == 'ckeditor') $files = [$fileField => [$files[$fileField]]]; //单文件补充为数组
      foreach ($files[$fileField] as $file) {
        $saveName   = Filesystem::disk($driver)->putFile('upload', $file);
        $domain = isset($config['cdn']) ? $config['cdn'] : $config['domain']; //优先使用cdn
        $fileUrl = $domain . '/' . str_replace('\\', '/', $saveName);
        if($driver=='cos') $fileUrl = $config['scheme'].'://'.$fileUrl; //腾讯上传补充前缀
        $dataList[] = [
          'driver'        => $driver,
          'original_name' => $file->getOriginalName(),
          'file_type'     => $this->getFileType($file->extension()),
          'file_url'      => $fileUrl,
          'file_size'     => $file->getSize(),
          'file_ext'      => $file->extension(),
          'uid'           => $this->loginInfo['uid'],
          'upload_time'   => time(),
          'group_id'      => $groupId,
        ];
      }
      $data = $this->model->saveAll($dataList);
    } catch (\Throwable $th) {
      if ($opener == 'ckeditor') {
        return json_encode(['uploaded' => 0, 'error' => ['message' => $th->getMessage()]]);
      } else {
        $this->error($th->getMessage());
      }
    }
    if ($opener == 'ckeditor') {
      return json_encode(['uploaded' => 1, 'fileName' => $data[0]['original_name'], 'url' => $data[0]['file_url']]);
    } else {
      $this->success('上传成功', '', $data);
    }
  }

  /**
   * 获取验证规则
   * @param string $type
   * @return array
   */
  private function getValidRule($type = 'image')
  {
    $rule = [
      "zip" => "zip,rar,tar,gzip,gz,7z",
      "code" => "php,js,css,htm,html",
      "audio" => "mp3",
      "image" => "jpg,jpeg,png,gif,bmp",
      "file" => "doc,docx,wps,xls,xlsx,csv,ppt,pptx,txt,md,jpg,jpeg,png,gif,bmp,mp3,MP4,mov,zip,rar,tar,gzip,gz,7z, WebM, Ogv,webp,svga",
      "xls" => "xls,xlsx,csv",
      "video" => "MP4, WebM, Ogv"
    ];
    return $rule[$type] ?? [];
  }

  /**
   * 获取文件类型
   * @param $ext
   * @return string
   */
  private function getFileType($ext)
  {
    $fileType = 'other';
    if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'bmp'])) $fileType = 'image';
    if (in_array($ext, ['xls', 'xlsx', 'csv'])) $fileType = 'xls';
    if (in_array($ext, ['doc', 'docx', 'wps'])) $fileType = 'doc';
    if (in_array($ext, ['txt'])) $fileType = 'txt';
    if (in_array($ext, ['ppt', 'pptx'])) $fileType = 'ppt';
    if (in_array($ext, ['pdf'])) $fileType = 'pdf';
    if (in_array($ext, ['php', 'js', 'css', 'htm', 'html'])) $fileType = 'code';
    if (in_array($ext, ['zip', 'rar', 'tar', 'gzip', 'gz', '7z'])) $fileType = 'zip';
    if (in_array($ext, [
      'flv', 'mkv', 'avi', 'rm', 'rmvb',
      'mpeg', 'mpg', 'ogg', 'ogv', 'mov',
      'wmv', 'mp4', 'webm', 'mid'
    ])) $fileType = 'video';
    if (in_array($ext, ['mp3'])) $fileType = 'audio';
    return $fileType;
  }
}
